﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using AngleSharp.Dom;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.PublisherStatAdposGeneralResponse.Types;

namespace WCS.Application.Service.Plc;
/// <summary>
/// WCS写入RGV指令地址表
/// </summary>
public class WcsReaderWriteRgv
{
    /// <summary>
    /// 读取MQTT数据
    /// </summary>
    public void ReadMqttData()
    {
        // 读取MQTT数据的逻辑
        Console.WriteLine("Reading MQTT data...");
    }
    /// <summary>
    /// 写入MQTT数据
    /// </summary>
    public void WriteMqttData()
    {
        // 写入MQTT数据的逻辑
        Console.WriteLine("Writing MQTT data...");
    }
    #region WCS写入RGV指令地址表


    // 新增的控制指令相关字段
    /// <summary>
    /// 控制指令字，1 表示正常行驶指令 （1：正常移动2：顶升控制3：强制移动4：查找定位点6：系统复位7：紧急停止8：IO控制（9：脉冲移动）11.继续执行上次指令）
    /// </summary>
    public ushort Wm000 { get; set; }

    /// <summary>
    /// 起始二维码码值
    /// </summary>
    public ushort Wm001 { get; set; }

    /// <summary>
    /// 中间二维码码值，0 表示无中间二维码
    /// </summary>
    public ushort Wm002 { get; set; }

    /// <summary>
    /// 目标二维码码值
    /// </summary>
    public ushort Wm003 { get; set; }

    /// <summary>
    /// 起点到目标点的距离长度（mm）
    /// </summary>
    public ushort Wm004_Wm005 { get; set; }

    /// <summary>
    /// 中间点到目标点的距离长度（mm）
    /// </summary>
    public ushort Wm006_Wm007 { get; set; }

    /// <summary>
    /// 小车运行方向
    /// </summary>
    public ushort Wm008 { get; set; }

    /// <summary>
    /// 小车运行速度
    /// </summary>
    public ushort Wm014 { get; set; }

    /// <summary>
    /// 指令结束位，所有指令必填项 取值1，每次下发指令都必须将此位置写入1，RGV才会执行指令，否则视
    /// </summary>
    public ushort Wm016 { get; set; }

    #endregion

    /// <summary>
    /// WCS心跳信号 每扫描周期 WCS更新一次对应值，每次值累加1
    /// </summary>
    public ushort Wm056 { get; set; } // 备用位，保留

    


}

/// <summary>
/// 反馈
/// </summary>
public class Feedback
{
    #region RGV反馈状态地址表

    /// <summary>
    /// RGV 指令状态位，0 表示空闲，1 表示忙  
    /// </summary>
    public ushort Wm200 { get; set; }

    /// <summary>
    /// 当前二维码，0 表示未扫描到码值，否则为实际扫描到的码值
    /// </summary>
    public ushort Wm201  { get; set; }

    /// <summary>
    /// 电池电量值，范围 0 - 1000（单位 0.1%），读取 int 值后除以 10
    /// </summary>
    public ushort Wm202 { get; set; }

    /// <summary>
    /// 电池温度，范围 0 - 1000（单位 0.1 度），读取 int 值后除以 1000
    /// </summary>
    public ushort Wm203 { get; set; }

    /// <summary>
    /// RGV 错误编号，0 无错误，1 升降伺服，2 行走伺服，3 运行错误，4 系统错误
    /// </summary>
    public ushort Wm204 { get; set; }

    /// <summary>
    /// RGV 顶升位置、充电开关状态位
    /// </summary>
    public ushort Wm205 { get; set; }

    /// <summary>
    /// RGV 错误信息码，用于查询对应错误信息
    /// </summary>
    public ushort Wm206 { get; set; }

    /// <summary>
    /// 雷达及托盘开关状态位
    /// </summary>
    public ushort Wm207 { get; set; }

    /// <summary>
    /// 二维码 X 方向偏移量，范围 -200 - 200（单位 MM），超出正负 100 视为扫描不到码值
    /// </summary>
    public ushort Wm209 { get; set; }

    /// <summary>
    /// 二维码 Y 方向偏移量，范围 -200 - 200（单位 MM），超出正负 100 视为扫描不到码值
    /// </summary>
    public ushort Wm210 { get; set; }

    /// <summary>
    /// 电池电压值，0 无效（单位 0.1V），读取 int 值后除以 100
    /// </summary>
    public ushort Wm211 { get; set; }

    /// <summary>
    /// 当前的高度值，范围 0 - 9000，顶升伺服的当前位置
    /// </summary>
    public ushort Wm212 { get; set; }
    #endregion

    /// <summary>  
    /// 获取 RGV 错误编号对应的错误信息  
    /// </summary>  
    /// <returns>错误信息字符串</returns>  
    public string GetError204()
    {
        return Wm204 switch
        {
            0 => "无错误",
            1 => "升降伺服错误",
            2 => "行走伺服错误",
            3 => "运行错误",
            4 => "系统错误",
            _ => "未知错误"
        };
    }

    /// <summary>  
    /// 根据传入的值判断并返回 RGV 顶升位置、换向位、中间位、充电位及电池反馈充电状态描述  
    /// </summary>  
    /// <param name="value">传入的 Wm205 值</param>  
    /// <returns>状态描述字符串</returns>  
    public string GetLift205StatusByValue(ushort value)
    {
        if (value == 0)
        {
            return "传入值无效或未设置";
        }
        //1-5
        var descriptions = new List<string>();

        if (IsBitSet(value, 1)) descriptions.Add("顶升位：处于顶升位");
        else descriptions.Add("1顶升位：不处于顶升位");
        if (IsBitSet(value, 2)) descriptions.Add("换向位：处于换向位");
        else descriptions.Add("换向位：不处于换向位");

        if (IsBitSet(value, 3)) descriptions.Add("中间位：处于中间位");
        else descriptions.Add("中间位：不处于中间位");

        if (IsBitSet(value, 4)) descriptions.Add("充电位：充电打开状态");
        else descriptions.Add("充电位：充电处于关闭状态");

        if (IsBitSet(value, 5)) descriptions.Add("电池反馈充电状态：充电打开");
        else descriptions.Add("电池反馈充电状态：充电关闭");

        return string.Join("，", descriptions);
    }

    /// <summary>  
    /// 获取 RGV 错误信息码对应的描述  
    /// </summary>  
    /// <returns>错误信息码描述字符串</returns>  
    public string GetErrorCodeDescription()
    {
        return Wm206 switch
        {
            0 => "无错误信息",
            1 => "伺服过载",
            2 => "通信故障",
            3 => "硬件故障",
            _ => "未知错误信息"
        };
    }

    /// <summary>  
    /// 获取雷达及托盘开关状态描述（c）  
    /// </summary>  
    /// <returns>状态描述字符串</returns>  
    public string GetRadar207ByBits(ushort n)
    {
        var descriptions = new List<string>();
        //0-6
        if ((n & 0b00000000) != 0) descriptions.Add("X+方向检测到障碍物");
        if ((n & 0b00000001) != 0) descriptions.Add("X-方向检测到障碍物");
        if ((n & 0b00000010) != 0) descriptions.Add("Y+方向检测到障碍物");
        if ((n & 0b00000100) != 0) descriptions.Add("Y-方向检测到障碍物");
        if ((n & 0b00001000) != 0) descriptions.Add("货位前检测到障碍物");
        if ((n & 0b00010000) != 0) descriptions.Add("货位后检测到障碍物");
        if ((n & 0b00100000) != 0) descriptions.Add("托盘检测位：检测到托盘");
        else descriptions.Add("托盘检测位：未检测到托盘");

        return string.Join("，", descriptions);
    }

    /// <summary>
    /// int 转bit0 1
    /// </summary>
    /// <param name="number"></param>
    /// <param name="bitPosition"></param>
    /// <returns></returns>
    static bool IsBitSet(ushort number, int bitPosition)
    {
        return (number & (1 << (bitPosition - 1))) != 0;
    }
}


